package com.ftar.urgent.util;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.util.Log;
import android.view.View;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;


/**
 * @author: wei.jin
 * @date: 2023/7/10
 * @email: wei.jin@fanttec.com
 * @description：
 */
public class FtBitmapUtils {
    public FtBitmapUtils() {
    }

    public static byte[] bitmap2bytes(Bitmap bitmap) {
        if (bitmap != null) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
            return baos.toByteArray();
        } else {
            return null;
        }
    }

    public static Bitmap loadBitmapFromView(View v) {
        //系统方法
        if (v == null) {
            return null;
        }

        Bitmap bmp = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        //利用bitmap生成画布
        Canvas canvas = new Canvas(bmp);
        //把view中的内容绘制在画布上
        v.draw(canvas);

        return bmp;
    }

    public static byte[] getNV21(int[] rgba, int inputWidth, int inputHeight) {
        byte[] yuv = new byte[inputWidth * inputHeight * 3 / 2];
        encodeYUV420SP(yuv, rgba, inputWidth, inputHeight);
        return yuv;
    }

    public static Bitmap mergeBitmap(Bitmap resBitmap, Bitmap desBitmap, int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas cv = new Canvas(bitmap);
        //draw bg into
        cv.drawBitmap(resBitmap, 0, 0, null);//在 0，0坐标开始画入bg
        //draw fg into
        cv.drawBitmap(desBitmap, 0, 0, null);//在 0，0坐标开始画入fg ，可以从任意位置画入
        //save all clip
        cv.save();//保存
        //store
        cv.restore();//存储

        return bitmap;
    }


    public static byte[] getNV21(Bitmap scaled, int inputWidth, int inputHeight) {

        int[] argb = new int[inputWidth * inputHeight];

        scaled.getPixels(argb, 0, inputWidth, 0, 0, inputWidth, inputHeight);

        byte[] yuv = new byte[inputWidth * inputHeight * 3 / 2];

        encodeYUV420SP(yuv, argb, inputWidth, inputHeight);

        scaled.recycle();

        return yuv;
    }



    /**
     * RGB转YUV420sp
     *
     * @param yuv420sp inputWidth * inputHeight * 3 / 2
     * @param argb     inputWidth * inputHeight
     * @param width
     * @param height
     */
    private static void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) {
        // 帧图片的像素大小
        final int frameSize = width * height;
        // ---YUV数据---
        int Y, U, V;
        // Y的index从0开始
        int yIndex = 0;
        // UV的index从frameSize开始
        int uvIndex = frameSize;

        // ---颜色数据---
        int a, R, G, B;
        int argbIndex = 0;

        // ---循环所有像素点，RGB转YUV---
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {

                // a is not used obviously
//                a = (argb[argbIndex] & 0xff000000) >> 24;
                R = (argb[argbIndex] & 0xff0000) >> 16;
                G = (argb[argbIndex] & 0xff00) >> 8;
                B = (argb[argbIndex] & 0xff);

                argbIndex++;

                // 优化后的算法
                Y = (306 * R + 601 * G + 117 * B) >> 10;
                U = ((-173 * R - 339 * G + 512 * B) >> 10) + 128;
                V = ((512 * R - 429 * G - 83 * B) >> 10) + 128;

                // 取最大值
                Y = Math.max(0, Math.min(Y, 255));
                U = Math.max(0, Math.min(U, 255));
                V = Math.max(0, Math.min(V, 255));

                // NV21 has a plane of Y and interleaved planes of VU each
                // sampled by a factor of 2
                // meaning for every 4 Y pixels there are 1 V and 1 U. Note the
                // sampling is every other
                // pixel AND every other scanline.
                // ---Y---
                yuv420sp[yIndex++] = (byte) Y;
                // ---UV---
                if ((j % 2 == 0) && (i % 2 == 0)) {
                    yuv420sp[uvIndex++] = (byte) V;
                    yuv420sp[uvIndex++] = (byte) U;
                }
            }
        }
    }


    public static Bitmap loadBitmap(byte[] bytes) {
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
    }

    public static Bitmap loadBitmap(InputStream inputStream) {
        return BitmapFactory.decodeStream(new BufferedInputStream(inputStream));
    }

    public static Bitmap loadBitmap(String path) {
        try {
            FileInputStream inputStream = new FileInputStream(path);
            Throwable var2 = null;

            Bitmap var3;
            try {
                var3 = BitmapFactory.decodeStream(inputStream);
            } catch (Throwable var13) {
                var2 = var13;
                throw var13;
            } finally {
                if (inputStream != null) {
                    if (var2 != null) {
                        try {
                            inputStream.close();
                        } catch (Throwable var12) {
                            var2.addSuppressed(var12);
                        }
                    } else {
                        inputStream.close();
                    }
                }

            }

            return var3;
        } catch (Exception var15) {
            var15.printStackTrace();
            return null;
        }
    }

    public static Bitmap loaBitmapdAssets(Context context, String assetsPath) {
        AssetManager am = context.getResources().getAssets();

        try {
            InputStream inputStream = am.open(assetsPath);
            return loadBitmap(inputStream);
        } catch (IOException var4) {
            var4.printStackTrace();
            return null;
        }
    }

    public static byte[] bitmap2pixel(Bitmap bmp) {
        int bytes = bmp.getByteCount();
        ByteBuffer buf = ByteBuffer.allocate(bytes);
        bmp.copyPixelsToBuffer(buf);
        return buf.array();
    }

    public static Bitmap pixel2bitmap(byte[] bytes, int width, int height, Bitmap.Config config) {
        Bitmap bmp = Bitmap.createBitmap(width, height, config);
        bmp.copyPixelsFromBuffer(ByteBuffer.wrap(bytes));
        return bmp;
    }

    public static Bitmap raga2Bitmap(int[] rgba, int w, int h) {
        return Bitmap.createBitmap(rgba, w, h, Bitmap.Config.ARGB_8888);
    }

    public static byte[] rgba2bytes(int[] argb, int width, int height) {
        Bitmap bp = Bitmap.createBitmap(argb, width, height, Bitmap.Config.ARGB_8888);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bp.compress(Bitmap.CompressFormat.JPEG, 80, baos);
        byte[] array = baos.toByteArray();
        return array;
    }

    public static byte[] yuv2bytes(byte[] bytes, int width, int height) {
        YuvImage yuvImage = new YuvImage(bytes, 17, width, height, (int[])null);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 100, baos);
        byte[] jpegs = baos.toByteArray();
        return jpegs;
    }

    public static Bitmap yuv2bitmap(byte[] bytes, int width, int height) {
        return loadBitmap(yuv2bytes(bytes, width, height));
    }

    public static byte[] bitmapPrimitiveBytes(Bitmap bmp) {
        int bytes = bmp.getByteCount();
        ByteBuffer buf = ByteBuffer.allocate(bytes);
        bmp.copyPixelsToBuffer(buf);
        return buf.array();
    }

    public static byte[] bitmapPrimitiveBytes(Bitmap bmp, float angle) {
        bmp = rotateBitmap(bmp, angle);
        int bytes = bmp.getByteCount();
        ByteBuffer buf = ByteBuffer.allocate(bytes);
        bmp.copyPixelsToBuffer(buf);
        return buf.array();
    }

    public static Bitmap convertGreyImage(byte[] values, int w, int h) {
        byte[] bytes = new byte[values.length];

        for(int i = 0; i < bytes.length; ++i) {
            bytes[i] = (byte)(255 - values[i]);
        }

        ByteBuffer bf = ByteBuffer.wrap(bytes);
        Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8);
        bm.copyPixelsFromBuffer(bf);
        return bm;
    }

    public static Bitmap bgrToBitmap(byte[] data, int width, int height) {
        Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        int row = height - 1;
        int col = width - 1;

        for(int i = data.length - 1; i >= 3; i -= 3) {
            int color = data[i - 2] & 255;
            color += data[i - 1] << 8 & '\uff00';
            color += data[i] << 16 & 16711680;
            bmp.setPixel(col--, row, color);
            if (col < 0) {
                col = width - 1;
                --row;
            }
        }

        return bmp;
    }

    public static Bitmap rotateBitmap(Bitmap origin, float angle) {
        if (origin == null) {
            return null;
        } else {
            int width = origin.getWidth();
            int height = origin.getHeight();
            Matrix matrix = new Matrix();
            matrix.postRotate(angle);
            Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
            if (newBM.equals(origin)) {
                return newBM;
            } else {
                origin.recycle();
                return newBM;
            }
        }
    }

    public static Bitmap getImageFromNet(String url) {
        HttpURLConnection conn = null;
        try {
            URL mURL = new URL(url);
            conn = (HttpURLConnection) mURL.openConnection();
            conn.setRequestMethod("GET"); //设置请求方法
            // conn.setConnectTimeout(10000);设置连接服务器超时时间
            conn.setReadTimeout(5000); //设置读取数据超时时间
            conn.connect(); //开始连接
            int responseCode = conn.getResponseCode();
            //得到服务器的响应码
            if (responseCode == 200) { //访问成功
                InputStream is = conn.getInputStream(); //获得服务器返回的流数据
                Bitmap bitmap = BitmapFactory.decodeStream(is); //根据流数据 创建一个bitmap对象
                return bitmap;
            } else { //访问失败
                Log.d("lyf--", "访问失败===responseCode：" + responseCode);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect(); //断开连接
            }
        }
        return null;
    }
}
